
import {Http, Log, Helper, Msg} from "@/core";
import {chooseFile} from './chooseFile.js';
import HttpConfig from '@/config/http';
/**
 * 文件上传核心处理器
 */
class Processor {
    constructor(uploader) {
        this.uploader = uploader;
    }

    before = null;
    upload = null;
    success = null;
    fail = null;
    complete = null;


    next({before, upload, success, fail, complete}) {
        this.before = before;
        this.upload = upload;
        this.success = success;
        this.fail = fail;
        this.complete = complete;
    }

    onBefore(before) {
        this.before = before;
    }

    onUpload(upload) {
        this.upload = upload;
    }

    onSuccess(success) {
        this.success = success;
    }

    onFail(fail) {
        this.fail = fail;
    }

    onComplete(complete) {
        this.complete = complete;
    }
}

const UPLOAD_TYPE = {
    IMAGE: 'image',
    FILE: 'file'
}

class Uploader {

    count = 1;
    ext = [];
    // sizeType = [];
    // sourceType = [];
    autoUpload = true;
    //为-1表示不限制大小
    limitSize = -1;
    url = HttpConfig.uploadUrl;
    type = UPLOAD_TYPE.IMAGE;
    formData = {};
    sourceType = null;

    setUrl(url) {
        this.url = url;
    }

    setCount(count) {
        this.count = count;
    }

    setSourceType(sourceType) {
        this.sourceType = sourceType;
    }

    setAccept(accept) {
        if(typeof accept == 'string') {
            this.ext = accept.split(",");
            return;
        }

        this.ext = Helper.empty(accept) ? [] : accept;
    }

    isAutoUpload(auto) {
        this.autoUpload = auto;
    }

    setLimitSize(size) {
        this.limitSize = size;
    }

    setType(type) {
        this.type = type;
    }

    setFormData(formData) {
        this.formData = formData;
    }


    choose() {
        if(this.type == UPLOAD_TYPE.IMAGE) {
            return this.chooseImage();
        } else {
            return this.chooseFile();
        }
    }

    chooseImage() {
        let processor = new Processor(this);
        let option = {
            count: this.count,
            success: (res) => {
                handlerResult(processor, res.tempFiles, false, this)
            },
            fail:(error) => {
                handlerResult(processor,[], error, this);
            }
        };
        if(! Helper.emptyArray(this.sourceType)){
            option.sourceType = this.sourceType;
        }

        // #ifdef MP-WEIXIN
        uni.authorize({
            scope: "scope.camera",
            success: () => {
                uni.chooseImage(option);
            },
            fail: (res) => {
                console.log(res);
                if(res.errMsg == "authorize:fail auth deny") {
                    Msg.confirm('检测到摄像头权限被拒绝，是否前往设置中心开启权限').then(_ => {
                        uni.openSetting()
                    })
                } else if(res.errno == 112) {
                    Msg.error("隐私政策未设置");
                } else {
                    Msg.error("未授权，请联系客服");
                }
            }
        })
        // #endif

        // #ifdef MP-ALIPAY
        uni.chooseImage(option);
        // #endif

        return processor;
    }

    chooseFile() {
		let processor = new Processor(this);
        let choose = null;
        // #ifdef APP-PLUS || H5
        //choose = uni.chooseFile;
		chooseFile(url => {
			if(Helper.empty(url)) {
				Msg.error("获取文件失败");
				return;
			}

			let name = "";
			let cut = url.lastIndexOf('/');
			if (cut != -1) {
				name = url.substring(cut + 1);
			}

			handlerResult(processor, [{name: name, path: url}], false, this)
		})
		return processor;
        // #endif

        // #ifdef MP-WEIXIN
        choose = wx.chooseMessageFile;
        let options = {
            count: this.count,
            type:  'all',
            success: (res) => {
                handlerResult(processor, res.tempFiles, false, this)
            },
            fail:(error) => {
                handlerResult(processor,[], error, this);
            }
        }

        if(! Helper.emptyArray(this.ext)) {
            options.extension = this.ext;
        }

        choose(options);
        // #endif

        // #ifdef MP-ALIPAY
        choose = my.getFileSystemManager();
        const list = choose.readdirSync(`${my.env.USER_DATA_PATH}`)
        // #endif


        return processor;
    }
}

/**
 * choose 返回参数
 * name: "logo.png"
 * path: "http://tmp/A6KdHMLPKpXubfff7393bd97fd8ac70ba834d0f1d7f5.png"
 * size: 50411
 * time: 1664249434
 * type: "image"
 * @param processor
 * @param fileList
 * @param error
 * @param uploader
 * @returns {Promise<boolean>}
 */
async function handlerResult(processor, fileList, error, uploader) {
    if(error) {
        if(error && (error.errMsg === 'chooseImage:fail cancel' || error.errMsg === 'chooseMessageFile:fail cancel')) {
            return false;
        }
        Log.error(error);
        processor.fail ? processor.fail(null, {code: 500, message: error.errMsg}) : Msg.error("选择文件失败");
        return false;
    }

    if(processor.before) {
        let isSuccess = await processor.before(fileList);
        if(! isSuccess) {
            return false;
        }
    }

    //todo 走自己的验证 如判断大小 和 类型
    for (let i=0;i<fileList.length;i++) {
        let file = fileList[i];

        if(uploader.limitSize > -1 && uploader.limitSize < file.size) {
            Msg.alert( "上传文件的大小已经超出限制的大小");
            return false;
        }

        if(file.path) {
            let ext = file.path.substr(file.path.lastIndexOf(".") + 1);
            if(! Helper.emptyArray(uploader.ext) && uploader.ext.indexOf(ext) === -1) {
                Msg.alert("上传文件类型不符合，只允许上传" + uploader.ext.join(","));
                return false;
            }
        }
    }

    if(! uploader.autoUpload) {
        processor.complete && processor.complete(fileList, []);
        return true;
    }

    let errorFileList = [];
    for (let i = 0; i < fileList.length; i++) {
        let file = fileList[i];
        Log.info("file:", file);
        if(! file.name) {
            file.name = file.path.substr(file.path.lastIndexOf("/") + 1)
        }

        let formData = Object.assign({}, uploader.formData);
        if(! formData.name) {
            formData.name = file.name;
        }

        Log.info("formData:", formData);

        Msg.loading(`文件上传中${i}/${fileList.length}`);
        const {data, code, message} = await Http.upload(file.path, formData, uploader.url).validate(false);
        let resp = {data, code, message}

        file.resp = resp;
        //todo file扩展出实际接口返回字段，比如name，fileId与id映射 url等等字段
        if(resp.code != 200) {
            errorFileList.push(file);
            processor.fail && processor.fail(file, resp);
            continue;
        }

        let resultData = resp.data;
        file.id = resultData.id;
        file.name = resultData.name;
        file.originalFilename = resultData.originalFilename;
        file.size = resultData.fileSize;
        file.url = file.path;
        file.path = resultData.filePath;
        processor.success && processor.success(file);
    }
    Msg.loading(false);
    if(processor.complete) {
        processor.complete(fileList, errorFileList);
        return true;
    }

    if(! Helper.emptyArray(errorFileList)) {
        if(errorFileList.length == 1) {
            let errorFile = errorFileList[0];
            Msg.alert(`${errorFile.name}文件上传失败：${errorFile.resp.message}`);
            return false;
        }

        Msg.alert("上传多个文件中存在上传失败的文件");
    }
}

export default Uploader;
